package ru.paswd.marketprice.rest.app.services;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import ru.paswd.marketprice.rest.api.exceptions.PriceHistoryItemAlreadyExistsException;
import ru.paswd.marketprice.rest.api.exceptions.ProductNotFoundException;
import ru.paswd.marketprice.rest.api.exceptions.ShopNotFoundException;
import ru.paswd.marketprice.rest.app.entity.Price;
import ru.paswd.marketprice.rest.app.entity.PriceHistoryItem;
import ru.paswd.marketprice.rest.app.entity.Product;
import ru.paswd.marketprice.rest.app.entity.Shop;
import ru.paswd.marketprice.rest.app.mappers.PriceMapper;
import ru.paswd.marketprice.rest.app.repositories.PriceHistoryRepository;
import ru.paswd.marketprice.rest.app.repositories.ProductsRepository;
import ru.paswd.marketprice.rest.app.repositories.ShopsRepository;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class PriceHistoryService {

    private final PriceHistoryRepository priceHistoryRepository;
    private final ShopsRepository shopsRepository;
    private final ProductsRepository productsRepository;

    private final PriceMapper priceMapper;

    public PriceHistoryItem savePrice(Price price) {
        if (priceHistoryRepository.existsByShopAndProductAndDateTime(
                price.getShop(), price.getProduct(), price.getDateTime())) {
            throw new PriceHistoryItemAlreadyExistsException();
        }

        PriceHistoryItem priceHistoryItem = priceMapper.toHistoryItem(price);
        return priceHistoryRepository.save(priceHistoryItem);
    }

    public List<ru.paswd.marketprice.rest.api.dto.Price> getHistory(
            UUID shopId, UUID productId) {

        Shop shop = shopsRepository.findById(shopId)
                .orElseThrow(ShopNotFoundException::new);

        Product product = productsRepository.findById(productId)
                .orElseThrow(ProductNotFoundException::new);

        return priceHistoryRepository
                .findAllByShopAndProductOrderByDateTimeAsc(shop, product).stream()
                .map(priceMapper::toDto)
                .collect(Collectors.toList());
    }
}
